/*
实验8-6 爱之匹配
分数 35
作者 陈越
单位 浙江大学

在 520 这个日子里，没有比开发一个约会 App 更合适做的事情了。这个软件的需求很简单，用户输入自己的性别、想要约会的异性的年龄范围 [a,b]、身高范围 [c,d]，你要帮所有用户匹配出系统中满足其约会条件的异性。注意：双方性别、年龄、身高的要求必须全都符合对方的要求才可以；每人最多只能匹配一位异性。
当然，同时让每个人都满意的目标其实很难达到，你只要尽力配成最多对就可以了。
输入格式：

输入第 1 行给出正整数 n (≤500) ，为系统中登记的用户人数。随后 n 行，每行给出一位用户的信息，格式如下：

性别 年龄 身高 a b c d

其中 性别 为 0 表示女性，1 表示男性，是该用户自己的性别；年龄 和 身高 也是用户自己的信息，均为不超过 200 的正整数；后面四个数字依次表示该用户想要约会的异性的年龄下限、年龄上限、身高下限、身高上限 —— 注意这里的范围都是闭区间，数字均为不超过 200 的正整数。同行数字间以 1 个空格分隔。
输出格式：

在一行中输出能够同时成功配对的最大对数。
输入样例：

7
0 23 165 23 35 170 180
1 25 178 22 25 160 170
0 25 175 26 40 180 190
1 38 184 22 36 170 180
1 28 180 20 30 165 175
0 36 172 36 40 180 190
1 37 181 25 36 172 175

输出样例：

3

用图的方式来解决。我们可以将用户建模为图中的节点，如果两个用户满足彼此的约会条件，则在他们之间画一条边。这样，问题就转化为在图中寻找最大匹配（Maximum Matching），即找到尽可能多的边，使得这些边之间没有共享的节点。
图的最大匹配问题

在图论中，最大匹配问题是指在一个图中找到一组边，使得这些边之间没有共同的节点，并且这组边的数量尽可能大。这个问题可以通过匈牙利算法（Hungarian Algorithm）或 Hopcroft-Karp 算法来解决。
*/

#include "../base/MGraph.cpp"

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

struct User {
    int gender;
    int age;
    int height;
    int minAge;
    int maxAge;
    int minHeight;
    int maxHeight;
};

bool canMatch(const User& a, const User& b) {
    if (a.gender == b.gender) return false; // 同性不能匹配
    if (a.age < b.minAge || a.age > b.maxAge) return false; // 年龄不符合
    if (a.height < b.minHeight || a.height > b.maxHeight) return false; // 身高不符合
    if (b.age < a.minAge || b.age > a.maxAge) return false; // 对方的年龄不符合
    if (b.height < a.minHeight || b.height > a.maxHeight) return false; // 对方的身高不符合
    return true;
}

// 匈牙利算法
bool bpm(int u, MGraph<int, int>& graph, vector<int>& pairTo, vector<bool>& visited) {
    int n = graph.get_num_vertex();
    for (int i = 0; i < n; ++i) {
        int v = i;
        if (graph.has_edge(u, v) && !visited[v]) {
            visited[v] = true;
            if (pairTo[v] == -1 || bpm(pairTo[v], graph, pairTo, visited)) {
                pairTo[v] = u;
                return true;
            }
        }
    }
    return false;
}

int maxMatching(MGraph<int, int>& graph, int n) {
    vector<int> pairTo(n, -1); // 记录匹配关系
    int result = 0;

    for (int u = 0; u < n; ++u) {
        vector<bool> visited(n, false); // 初始化访问标记
        if (bpm(u, graph, pairTo, visited)) {
            result++;
        }
    }
    return result;
}

int main() {
    int n;
    cin >> n;
    vector<User> users(n);

    for (int i = 0; i < n; ++i) {
        cin >> users[i].gender >> users[i].age >> users[i].height
            >> users[i].minAge >> users[i].maxAge >> users[i].minHeight >> users[i].maxHeight;
    }

    // 建图
    MGraph<int, int> graph(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i != j && canMatch(users[i], users[j])) {
                graph.add_edge(i, j);
            }
        }
    }

    // 计算最大匹配
    int matchedPairs = maxMatching(graph, n);

    // 输出结果
    cout << matchedPairs / 2 << endl; // 每对匹配被计算了两次，所以除以 2

    return 0;
}